package com.example.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import com.example.mapper.AdminMapper;
import com.example.pojo.entity.*;
import com.example.pojo.utils.LoginUser;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * TODO
 *
 * @author ding
 * @since 2024/7/23
 */
@Service
public class SpringSecurityDetailsService implements UserDetailsService {
    @Autowired
    private AdminMapper adminMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        MPJLambdaWrapper<Admin> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper
                .selectAll(Admin.class)
                .selectCollection(Role.class, Admin::getRoles,set -> set.collection(Permission.class, Role::getPermissions))
                .innerJoin(UserAndRole.class, UserAndRole::getUserId, Admin::getId)
                .innerJoin(Role.class, Role::getId, UserAndRole::getRoleId)
                .innerJoin(RoleAndPermission.class, RoleAndPermission::getRoleId, Role::getId)
                .innerJoin(Permission.class, Permission::getId, RoleAndPermission::getPermissionId)
                .eq(StringUtils.hasLength(username), Admin::getUsername, username);
        Admin admin = adminMapper.selectJoinOne(Admin.class, mpjLambdaWrapper);
        if (ObjectUtil.isNull(admin)) {
            throw new RuntimeException("当前用户不存在");
        }

        //封装LoginUser对象 包含账户名 密码 是否可用
        LoginUser loginUser = new LoginUser(admin);

        //将Authentication对象（用户信息，已认证转态、权限信息） 存入 SecurityContextConfig
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        return loginUser;
    }
}
